home *** CD-ROM | disk | FTP | other *** search
/ Programming a Multiplayer FPS in DirectX / Programming a Multiplayer FPS in DirectX (Companion CD).iso / DirectX / dxsdk_oct2004.exe / dxsdk.exe / Samples / C++ / Direct3D / DXTex / dxtexdoc.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-09-27  |  46.9 KB  |  1,594 lines

  1. // dxtexDoc.cpp : implementation of the CDxtexDoc class
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "dxtex.h"
  6. #include "dxtexDoc.h"
  7. #include "dialogs.h"
  8. #include "formats.h"
  9. #include "dds.h"
  10.  
  11. #ifdef _DEBUG
  12. #define new DEBUG_NEW
  13. #undef THIS_FILE
  14. static char THIS_FILE[] = __FILE__;
  15. #endif
  16.  
  17. // Helper function that tells whether the given D3DFMT has a working alpha channel
  18. BOOL FormatContainsAlpha( D3DFORMAT fmt )
  19. {
  20.     BOOL bHasAlpha = FALSE;
  21.  
  22.     for( int i=0; i < fmtInfoArraySize; i++ )
  23.     {
  24.         if( fmtInfoArray[i].fmt == fmt )
  25.         {
  26.             bHasAlpha = fmtInfoArray[i].bHasAlpha;
  27.             break;
  28.         }
  29.     }
  30.  
  31.     return bHasAlpha;
  32. }
  33.  
  34. /////////////////////////////////////////////////////////////////////////////
  35. // CDxtexDoc
  36.  
  37. IMPLEMENT_DYNCREATE(CDxtexDoc, CDocument)
  38.  
  39. BEGIN_MESSAGE_MAP(CDxtexDoc, CDocument)
  40.     //{{AFX_MSG_MAP(CDxtexDoc)
  41.     ON_COMMAND(ID_FILE_OPENALPHA, OnFileOpenAlpha)
  42.     ON_COMMAND(ID_FORMAT_GENERATEMIPMAPS, OnGenerateMipMaps)
  43.     ON_COMMAND(ID_FORMAT_CHANGESURFACEFMT, OnFormatChangeSurfaceFmt)
  44.     ON_COMMAND(ID_FORMAT_CHANGECUBEMAPFACES, OnFormatChangeCubeMapFaces)
  45.     ON_COMMAND(ID_FORMAT_MAKEINTOVOLUMEMAP, OnFormatMakeIntoVolumeMap)
  46.     ON_COMMAND(ID_FORMAT_RESIZE, OnFormatResize)
  47.     ON_UPDATE_COMMAND_UI(ID_FILE_OPENALPHA, OnUpdateFileOpenAlpha)
  48.     ON_UPDATE_COMMAND_UI(ID_FORMAT_GENERATEMIPMAPS, OnUpdateFormatGenerateMipmaps)
  49.     ON_UPDATE_COMMAND_UI(ID_FORMAT_CHANGECUBEMAPFACES, OnUpdateFormatChangeCubeMapFaces)
  50.     ON_UPDATE_COMMAND_UI(ID_FORMAT_MAKEINTOVOLUMEMAP, OnUpdateFormatMakeIntoVolumeMap)
  51.     ON_UPDATE_COMMAND_UI(ID_FORMAT_RESIZE, OnUpdateFormatResize)
  52.     //}}AFX_MSG_MAP
  53. END_MESSAGE_MAP()
  54.  
  55. /////////////////////////////////////////////////////////////////////////////
  56. // CDxtexDoc diagnostics
  57.  
  58. #ifdef _DEBUG
  59. void CDxtexDoc::AssertValid() const
  60. {
  61.     CDocument::AssertValid();
  62. }
  63.  
  64. void CDxtexDoc::Dump(CDumpContext& dc) const
  65. {
  66.     CDocument::Dump(dc);
  67. }
  68. #endif //_DEBUG
  69.  
  70. /////////////////////////////////////////////////////////////////////////////
  71. // CDxtexDoc construction/destruction
  72.  
  73. CDxtexDoc::CDxtexDoc()
  74. {
  75.     m_ptexOrig = NULL;
  76.     m_ptexNew = NULL;
  77.     m_dwWidth = 0;
  78.     m_dwHeight = 0;
  79.     m_dwDepth = 0;
  80.     m_numMips = 0;
  81.     m_dwCubeMapFlags = 0;
  82.     m_bTitleModsChanged = FALSE;
  83. }
  84.  
  85.  
  86. CDxtexDoc::~CDxtexDoc()
  87. {
  88.     ReleasePpo(&m_ptexOrig);
  89.     ReleasePpo(&m_ptexNew);
  90. }
  91.  
  92.  
  93. BOOL CDxtexDoc::OnNewDocument()
  94. {
  95.     HRESULT hr;
  96.     LPDIRECT3DDEVICE9 pd3ddev = PDxtexApp()->Pd3ddev();
  97.  
  98.     if (!CDocument::OnNewDocument())
  99.         return FALSE;
  100.  
  101.     CNewTextureDlg dlg;
  102.  
  103.     // Obtain maximum texture dimension
  104.     D3DCAPS9 d3dcaps;
  105.     if ( SUCCEEDED( pd3ddev->GetDeviceCaps( &d3dcaps ) ) )
  106.     {
  107.         dlg.SetMaxTextureSize( d3dcaps.MaxTextureWidth, d3dcaps.MaxTextureHeight );
  108.     }
  109.  
  110.     if (IDCANCEL == dlg.DoModal())
  111.         return FALSE;
  112.  
  113.     m_dwWidth = dlg.m_dwWidth;
  114.     m_dwHeight = dlg.m_dwHeight;
  115.     m_numMips = dlg.m_numMips;
  116.  
  117.     if (dlg.m_iTexType == 0)
  118.     {
  119.         LPDIRECT3DTEXTURE9 pmiptex;
  120.         hr = pd3ddev->CreateTexture(m_dwWidth, m_dwHeight, m_numMips, 
  121.             0, dlg.m_fmt, D3DPOOL_MANAGED, &pmiptex, NULL);
  122.         if (FAILED(hr))
  123.         {
  124.             AfxMessageBox(ID_ERROR_CANTCREATETEXTURE);
  125.             return FALSE;
  126.         }
  127.         m_ptexOrig = pmiptex;
  128.  
  129.     }
  130.     else if (dlg.m_iTexType == 1)
  131.     {
  132.         // Cube Map
  133.         LPDIRECT3DCUBETEXTURE9 pcubetex;
  134.         m_dwCubeMapFlags = DDS_CUBEMAP_ALLFACES;
  135.         hr = pd3ddev->CreateCubeTexture(m_dwWidth, m_numMips, 
  136.             0, dlg.m_fmt, D3DPOOL_MANAGED, &pcubetex, NULL);
  137.         if (FAILED(hr))
  138.         {
  139.             AfxMessageBox(ID_ERROR_CANTCREATETEXTURE);
  140.             return FALSE;
  141.         }
  142.         m_ptexOrig = pcubetex;
  143.     }
  144.     else
  145.     {
  146.         LPDIRECT3DVOLUMETEXTURE9 pvoltex;
  147.         m_dwDepth = dlg.m_dwDepth;
  148.         hr = pd3ddev->CreateVolumeTexture(m_dwWidth, m_dwHeight, m_dwDepth, m_numMips, 
  149.             0, dlg.m_fmt, D3DPOOL_SYSTEMMEM, &pvoltex, NULL);
  150.         if (FAILED(hr))
  151.         {
  152.             AfxMessageBox(ID_ERROR_CANTCREATETEXTURE);
  153.             return FALSE;
  154.         }
  155.         m_ptexOrig = pvoltex;
  156.     }
  157.  
  158.     return TRUE;
  159. }
  160.  
  161.  
  162. BOOL CDxtexDoc::OnOpenDocument(LPCTSTR lpszPathName)
  163. {
  164.     LPDIRECT3DDEVICE9 pd3ddev = PDxtexApp()->Pd3ddev();
  165.     D3DXIMAGE_INFO imageinfo;
  166.     D3DXIMAGE_INFO imageinfo2;
  167.  
  168.     if( FAILED( D3DXGetImageInfoFromFile( lpszPathName, &imageinfo ) ) )
  169.     {
  170.         AfxMessageBox(ID_ERROR_COULDNTLOADFILE);
  171.         return FALSE;
  172.     }
  173.  
  174.     switch( imageinfo.ResourceType )
  175.     {
  176.     case D3DRTYPE_TEXTURE:
  177.         if( FAILED( D3DXCreateTextureFromFileEx( pd3ddev, lpszPathName, 
  178.             imageinfo.Width, imageinfo.Height, imageinfo.MipLevels, 0,
  179.             imageinfo.Format, D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_FILTER_NONE, 0, 
  180.             &imageinfo2, NULL, (LPDIRECT3DTEXTURE9*)&m_ptexOrig ) ) )
  181.         {
  182.             AfxMessageBox(ID_ERROR_COULDNTLOADFILE);
  183.             return FALSE;
  184.         }
  185.         m_dwWidth = imageinfo2.Width;
  186.         m_dwHeight = imageinfo2.Height;
  187.         m_dwDepth = 0;
  188.         m_numMips = imageinfo2.MipLevels;
  189.  
  190.         if( imageinfo.ImageFileFormat == D3DXIFF_BMP )
  191.         {
  192.             // Look for "foo_a.bmp" for alpha channel
  193.             CString strPath = lpszPathName;
  194.             int i = strPath.ReverseFind('.');
  195.             HRESULT hr;
  196.             strPath = strPath.Left(i) + "_a.bmp";
  197.             CFileStatus status;
  198.             if (CFile::GetStatus(strPath, status))
  199.             {
  200.                 // Make sure there's an alpha channel to load alpha image into
  201.                 if (FAILED(EnsureAlpha(&m_ptexOrig)))
  202.                     return FALSE;
  203.  
  204.                 LPDIRECT3DSURFACE9 psurf;
  205.  
  206.                 hr = ((LPDIRECT3DTEXTURE9)m_ptexOrig)->GetSurfaceLevel(0, &psurf);
  207.                 if (FAILED(hr))
  208.                     return FALSE;
  209.  
  210.                 hr = LoadAlphaIntoSurface(strPath, psurf);
  211.                 ReleasePpo(&psurf);
  212.                 if (FAILED(hr))
  213.                     return FALSE;
  214.  
  215.             }
  216.         }
  217.         break;
  218.  
  219.     case D3DRTYPE_VOLUMETEXTURE:
  220.         if( FAILED( D3DXCreateVolumeTextureFromFileEx( pd3ddev, lpszPathName, 
  221.             imageinfo.Width, imageinfo.Height, imageinfo.Depth, imageinfo.MipLevels,
  222.             0, imageinfo.Format, D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_FILTER_NONE,
  223.             0, &imageinfo2, NULL, (LPDIRECT3DVOLUMETEXTURE9*)&m_ptexOrig ) ) )
  224.         {
  225.             AfxMessageBox(ID_ERROR_COULDNTLOADFILE);
  226.             return FALSE;
  227.         }
  228.         m_dwWidth = imageinfo2.Width;
  229.         m_dwHeight = imageinfo2.Height;
  230.         m_dwDepth = imageinfo2.Depth;
  231.         m_numMips = imageinfo2.MipLevels;
  232.         break;
  233.  
  234.     case D3DRTYPE_CUBETEXTURE:
  235.         if( FAILED( D3DXCreateCubeTextureFromFileEx( pd3ddev, lpszPathName, 
  236.             imageinfo.Width, imageinfo.MipLevels, 0, imageinfo.Format, 
  237.             D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_FILTER_NONE, 
  238.             0, &imageinfo2, NULL, (LPDIRECT3DCUBETEXTURE9*)&m_ptexOrig ) ) )
  239.         {
  240.             AfxMessageBox(ID_ERROR_COULDNTLOADFILE);
  241.             return FALSE;
  242.         }
  243.         m_dwWidth = imageinfo2.Width;
  244.         m_dwHeight = imageinfo2.Height;
  245.         m_dwDepth = 0;
  246.         m_numMips = imageinfo2.MipLevels;
  247.         m_dwCubeMapFlags = DDS_CUBEMAP_ALLFACES;
  248.         break;
  249.  
  250.     default:
  251.         AfxMessageBox(ID_ERROR_COULDNTLOADFILE);
  252.         return FALSE;
  253.     }
  254.  
  255.     return TRUE;
  256. }
  257.  
  258.  
  259. BOOL CDxtexDoc::OnSaveDocument(LPCTSTR lpszPathName)
  260. {
  261.     LPDIRECT3DBASETEXTURE9 ptex;
  262.     ptex = (m_ptexNew == NULL ? m_ptexOrig : m_ptexNew);
  263.     
  264.     if( FAILED( D3DXSaveTextureToFile( lpszPathName, D3DXIFF_DDS, ptex, NULL ) ) )
  265.     {
  266.         AfxMessageBox(ID_ERROR_COULDNTSAVEFILE);
  267.         return FALSE;
  268.     }
  269.     
  270.     SetModifiedFlag(FALSE);
  271.  
  272.     return TRUE;
  273. }
  274.  
  275.  
  276.  
  277.  
  278. D3DFORMAT CDxtexDoc::GetFormat(LPDIRECT3DBASETEXTURE9 ptex)
  279. {
  280.     LPDIRECT3DTEXTURE9 pmiptex = NULL;
  281.     LPDIRECT3DCUBETEXTURE9 pcubetex = NULL;
  282.     LPDIRECT3DVOLUMETEXTURE9 pvoltex = NULL;
  283.     D3DFORMAT fmt = D3DFMT_UNKNOWN;
  284.  
  285.     if (IsVolumeMap())
  286.         pvoltex = (LPDIRECT3DVOLUMETEXTURE9)ptex;
  287.     else if (IsCubeMap())
  288.         pcubetex = (LPDIRECT3DCUBETEXTURE9)ptex;
  289.     else
  290.         pmiptex = (LPDIRECT3DTEXTURE9)ptex;
  291.  
  292.     if (pvoltex != NULL)
  293.     {
  294.         D3DVOLUME_DESC vd;
  295.         pvoltex->GetLevelDesc(0, &vd);
  296.         fmt = vd.Format;
  297.     }
  298.     else if (pcubetex != NULL)
  299.     {
  300.         D3DSURFACE_DESC sd;
  301.         pcubetex->GetLevelDesc(0, &sd);
  302.         fmt = sd.Format;
  303.     }
  304.     else if( pmiptex != NULL )
  305.     {
  306.         D3DSURFACE_DESC sd;
  307.         pmiptex->GetLevelDesc(0, &sd);
  308.         fmt = sd.Format;
  309.     }
  310.     return fmt;
  311. }
  312.  
  313.  
  314.  
  315. // If *pptex's current format has less than 4 bits of alpha, change
  316. // it to a similar format that has at least 4 bits of alpha.
  317. HRESULT CDxtexDoc::EnsureAlpha(LPDIRECT3DBASETEXTURE9* pptex)
  318. {
  319.     HRESULT hr;
  320.     D3DFORMAT fmtCur = GetFormat(*pptex);
  321.     D3DFORMAT fmtNew = D3DFMT_UNKNOWN;
  322.     LPDIRECT3DBASETEXTURE9 ptex = NULL;
  323.  
  324.     switch (fmtCur)
  325.     {
  326.     case D3DFMT_R8G8B8:
  327.         fmtNew = D3DFMT_A8R8G8B8;
  328.         break;
  329.     default:
  330.         break;
  331.     }
  332.  
  333.     if( fmtNew != D3DFMT_UNKNOWN )
  334.     {
  335.         if (FAILED(hr = ChangeFormat(m_ptexOrig, fmtNew, &ptex)))
  336.             return hr;
  337.         ReleasePpo(&m_ptexOrig);
  338.         m_ptexOrig = ptex;
  339.     }
  340.  
  341.     return S_OK;
  342. }
  343.  
  344.  
  345.  
  346.  
  347. /////////////////////////////////////////////////////////////////////////////
  348. // CDxtexDoc commands
  349.  
  350. HRESULT CDxtexDoc::LoadAlphaBmp(CString& strPath)
  351. {
  352.     HRESULT hr;
  353.     LPDIRECT3DTEXTURE9 pmiptex;
  354.     LPDIRECT3DSURFACE9 psurf;
  355.  
  356.     if (IsCubeMap())
  357.         return E_FAIL;
  358.  
  359.     pmiptex = (LPDIRECT3DTEXTURE9)m_ptexOrig;
  360.     hr = pmiptex->GetSurfaceLevel(0, &psurf);
  361.     if (FAILED(hr))
  362.         return hr;
  363.  
  364.     hr = LoadAlphaIntoSurface(strPath, psurf);
  365.     ReleasePpo(&psurf);
  366.     if (FAILED(hr))
  367.         return hr;
  368.     
  369.     UpdateAllViews(NULL, 1); // tell CView to pick up new surface pointers
  370.     return S_OK;
  371. }
  372.  
  373.  
  374.  
  375.  
  376. HRESULT CDxtexDoc::ChangeFormat(LPDIRECT3DBASETEXTURE9 ptexCur, D3DFORMAT fmtTo, 
  377.                                 LPDIRECT3DBASETEXTURE9* pptexNew)
  378. {
  379.     HRESULT hr;
  380.     LPDIRECT3DDEVICE9 pd3ddev = PDxtexApp()->Pd3ddev();
  381.     LPDIRECT3DTEXTURE9 pmiptex;
  382.     LPDIRECT3DCUBETEXTURE9 pcubetex;
  383.     LPDIRECT3DVOLUMETEXTURE9 pvoltex;
  384.     D3DFORMAT fmtFrom;
  385.     LPDIRECT3DTEXTURE9 pmiptexNew;
  386.     LPDIRECT3DCUBETEXTURE9 pcubetexNew;
  387.     LPDIRECT3DVOLUMETEXTURE9 pvoltexNew;
  388.  
  389.     if (IsVolumeMap())
  390.     {
  391.         pvoltex = (LPDIRECT3DVOLUMETEXTURE9)ptexCur;
  392.         D3DVOLUME_DESC vd;
  393.         pvoltex->GetLevelDesc(0, &vd);
  394.         fmtFrom = vd.Format;
  395.     }
  396.     else if (IsCubeMap())
  397.     {
  398.         pcubetex = (LPDIRECT3DCUBETEXTURE9)ptexCur;
  399.         D3DSURFACE_DESC sd;
  400.         pcubetex->GetLevelDesc(0, &sd);
  401.         fmtFrom = sd.Format;
  402.     }
  403.     else
  404.     {
  405.         pmiptex = (LPDIRECT3DTEXTURE9)ptexCur;
  406.         D3DSURFACE_DESC sd;
  407.         pmiptex->GetLevelDesc(0, &sd);
  408.         fmtFrom = sd.Format;
  409.     }
  410.  
  411.     if (fmtFrom == D3DFMT_DXT2 || fmtFrom == D3DFMT_DXT4)
  412.     {
  413.         if (fmtTo == D3DFMT_DXT1)
  414.         {
  415.             AfxMessageBox(ID_ERROR_PREMULTTODXT1);
  416.         }
  417.         else if (fmtTo != D3DFMT_DXT2 && fmtTo != D3DFMT_DXT4)
  418.         {
  419.             AfxMessageBox(ID_ERROR_PREMULTALPHA);
  420.             return S_OK;
  421.         }
  422.     }
  423.  
  424.     if (IsVolumeMap())
  425.     {
  426.         hr = pd3ddev->CreateVolumeTexture(m_dwWidth, m_dwHeight, m_dwDepth, m_numMips,
  427.             0, fmtTo, D3DPOOL_SYSTEMMEM, &pvoltexNew, NULL);
  428.         if (FAILED(hr))
  429.             return hr;
  430.         *pptexNew = pvoltexNew;
  431.         if (FAILED(BltAllLevels(D3DCUBEMAP_FACE_FORCE_DWORD, ptexCur, *pptexNew)))
  432.             return hr;
  433.     }
  434.     else if (IsCubeMap())
  435.     {
  436.         hr = pd3ddev->CreateCubeTexture(m_dwWidth, m_numMips, 
  437.              0, fmtTo, D3DPOOL_MANAGED, &pcubetexNew, NULL);
  438.         if (FAILED(hr))
  439.             return hr;
  440.         *pptexNew = pcubetexNew;
  441.         if (FAILED(hr = BltAllLevels(D3DCUBEMAP_FACE_NEGATIVE_X, ptexCur, *pptexNew)))
  442.             return hr;
  443.         if (FAILED(hr = BltAllLevels(D3DCUBEMAP_FACE_POSITIVE_X, ptexCur, *pptexNew)))
  444.             return hr;
  445.         if (FAILED(hr = BltAllLevels(D3DCUBEMAP_FACE_NEGATIVE_Y, ptexCur, *pptexNew)))
  446.             return hr;
  447.         if (FAILED(hr = BltAllLevels(D3DCUBEMAP_FACE_POSITIVE_Y, ptexCur, *pptexNew)))
  448.             return hr;
  449.         if (FAILED(hr = BltAllLevels(D3DCUBEMAP_FACE_NEGATIVE_Z, ptexCur, *pptexNew)))
  450.             return hr;
  451.         if (FAILED(hr = BltAllLevels(D3DCUBEMAP_FACE_POSITIVE_Z, ptexCur, *pptexNew)))
  452.             return hr;
  453.     }
  454.     else
  455.     {
  456.         if ((fmtTo == D3DFMT_DXT1 || fmtTo == D3DFMT_DXT2 ||
  457.             fmtTo == D3DFMT_DXT3 || fmtTo == D3DFMT_DXT4 ||
  458.             fmtTo == D3DFMT_DXT5) && (m_dwWidth % 4 != 0 || m_dwHeight % 4 != 0))
  459.         {
  460.             AfxMessageBox(ID_ERROR_NEEDMULTOF4);
  461.             return E_FAIL;
  462.         }
  463.  
  464.         hr = pd3ddev->CreateTexture(m_dwWidth, m_dwHeight, m_numMips, 
  465.              0, fmtTo, D3DPOOL_MANAGED, &pmiptexNew, NULL);
  466.         if (FAILED(hr))
  467.             return hr;
  468.         *pptexNew = pmiptexNew;
  469.         if (FAILED(BltAllLevels(D3DCUBEMAP_FACE_FORCE_DWORD, ptexCur, *pptexNew)))
  470.             return hr;
  471.     }
  472.     return S_OK;
  473. }
  474.  
  475.  
  476.  
  477.  
  478. HRESULT CDxtexDoc::Compress(D3DFORMAT fmtTo, BOOL bSwitchView)
  479. {
  480.     HRESULT hr;
  481.     LPDIRECT3DBASETEXTURE9 ptexNew = NULL;
  482.  
  483.     if (FAILED(hr = ChangeFormat(m_ptexOrig, fmtTo, &ptexNew)))
  484.         return hr;
  485.  
  486.     ReleasePpo(&m_ptexNew);
  487.     m_ptexNew = ptexNew;
  488.  
  489.     SetModifiedFlag();
  490.     m_bTitleModsChanged = TRUE; // force title bar update
  491.     if (bSwitchView)
  492.     {
  493.         if( AfxGetMainWnd() != NULL )
  494.             AfxGetMainWnd()->PostMessage(WM_COMMAND, ID_VIEW_COMPRESSED, 0);
  495.     }
  496.  
  497.     return S_OK;
  498. }
  499.  
  500.  
  501.  
  502.  
  503. void CDxtexDoc::OnGenerateMipMaps() 
  504. {
  505.     GenerateMipMaps();
  506. }
  507.  
  508.  
  509.  
  510.  
  511. void CDxtexDoc::GenerateMipMaps() 
  512. {
  513.     LONG lwTempH;
  514.     LONG lwTempW;
  515.     LONG lwPowsW;
  516.     LONG lwPowsH;
  517.     LPDIRECT3DTEXTURE9 pddsNew = NULL;
  518.     D3DFORMAT fmt;
  519.     HRESULT hr;
  520.     LPDIRECT3DDEVICE9 pd3ddev = PDxtexApp()->Pd3ddev();
  521.     LPDIRECT3DTEXTURE9 pmiptex = NULL;
  522.     LPDIRECT3DCUBETEXTURE9 pcubetex = NULL;
  523.     LPDIRECT3DVOLUMETEXTURE9 pvoltex = NULL;
  524.     LPDIRECT3DTEXTURE9 pmiptexNew = NULL;
  525.     LPDIRECT3DCUBETEXTURE9 pcubetexNew = NULL;
  526.     LPDIRECT3DVOLUMETEXTURE9 pvoltexNew = NULL;
  527.     LPDIRECT3DSURFACE9 psurfSrc;
  528.     LPDIRECT3DSURFACE9 psurfDest;
  529.     LPDIRECT3DVOLUME9 pvolSrc;
  530.     LPDIRECT3DVOLUME9 pvolDest;
  531.  
  532.     if (IsVolumeMap())
  533.         pvoltex = (LPDIRECT3DVOLUMETEXTURE9)m_ptexOrig;
  534.     else if (IsCubeMap())
  535.         pcubetex = (LPDIRECT3DCUBETEXTURE9)m_ptexOrig;
  536.     else
  537.         pmiptex = (LPDIRECT3DTEXTURE9)m_ptexOrig;
  538.  
  539.     if (pvoltex != NULL)
  540.     {
  541.         D3DVOLUME_DESC vd;
  542.         pvoltex->GetLevelDesc(0, &vd);
  543.         fmt = vd.Format;
  544.     }
  545.     else if (pcubetex != NULL)
  546.     {
  547.         D3DSURFACE_DESC sd;
  548.         pcubetex->GetLevelDesc(0, &sd);
  549.         fmt = sd.Format;
  550.     }
  551.     else
  552.     {
  553.         D3DSURFACE_DESC sd;
  554.         pmiptex->GetLevelDesc(0, &sd);
  555.         fmt = sd.Format;
  556.     }
  557.  
  558.     lwTempW = m_dwWidth;
  559.     lwTempH = m_dwHeight;
  560.     lwPowsW = 0;
  561.     lwPowsH = 0;
  562.     while (lwTempW > 0)
  563.     {
  564.         lwPowsW++;
  565.         lwTempW = lwTempW / 2;
  566.     }
  567.     while (lwTempH > 0)
  568.     {
  569.         lwPowsH++;
  570.         lwTempH = lwTempH / 2;
  571.     }
  572.     m_numMips = lwPowsW > lwPowsH ? lwPowsW : lwPowsH;
  573.  
  574.     // Create destination mipmap surface - same format as source
  575.     if (pvoltex != NULL)
  576.     {
  577.         if (FAILED(hr = pd3ddev->CreateVolumeTexture(m_dwWidth, m_dwHeight, m_dwDepth, 
  578.             m_numMips, 0, fmt, D3DPOOL_SYSTEMMEM, &pvoltexNew, NULL)))
  579.         {
  580.             goto LFail;
  581.         }
  582.         hr = pvoltex->GetVolumeLevel(0, &pvolSrc);
  583.         hr = pvoltexNew->GetVolumeLevel(0, &pvolDest);
  584.         hr = D3DXLoadVolumeFromVolume(pvolDest, NULL, NULL, pvolSrc, NULL, NULL, 
  585.             D3DX_FILTER_TRIANGLE, 0);
  586.         ReleasePpo(&pvolSrc);
  587.         ReleasePpo(&pvolDest);
  588.         hr = D3DXFilterVolumeTexture(pvoltexNew, NULL, 0, D3DX_FILTER_TRIANGLE);
  589.     }
  590.     else if (pmiptex != NULL)
  591.     {
  592.         if (FAILED(hr = pd3ddev->CreateTexture(m_dwWidth, m_dwHeight, m_numMips, 
  593.              0, fmt, D3DPOOL_MANAGED, &pmiptexNew, NULL)))
  594.         {
  595.             goto LFail;
  596.         }
  597.         hr = pmiptex->GetSurfaceLevel(0, &psurfSrc);
  598.         hr = pmiptexNew->GetSurfaceLevel(0, &psurfDest);
  599.         hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL, 
  600.             D3DX_FILTER_TRIANGLE, 0);
  601.         ReleasePpo(&psurfSrc);
  602.         ReleasePpo(&psurfDest);
  603.         hr = D3DXFilterTexture(pmiptexNew, NULL, 0, D3DX_FILTER_TRIANGLE);
  604.     }
  605.     else
  606.     {
  607.         if (FAILED(hr = pd3ddev->CreateCubeTexture(m_dwWidth, m_numMips, 
  608.              0, fmt, D3DPOOL_MANAGED, &pcubetexNew, NULL)))
  609.         {
  610.             goto LFail;
  611.         }
  612.         hr = pcubetex->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_X, 0, &psurfSrc);
  613.         hr = pcubetexNew->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_X, 0, &psurfDest);
  614.         hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL, 
  615.             D3DX_FILTER_TRIANGLE, 0);
  616.         ReleasePpo(&psurfSrc);
  617.         ReleasePpo(&psurfDest);
  618.         hr = pcubetex->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_X, 0, &psurfSrc);
  619.         hr = pcubetexNew->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_X, 0, &psurfDest);
  620.         hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL, 
  621.             D3DX_FILTER_TRIANGLE, 0);
  622.         ReleasePpo(&psurfSrc);
  623.         ReleasePpo(&psurfDest);
  624.         hr = pcubetex->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_Y, 0, &psurfSrc);
  625.         hr = pcubetexNew->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_Y, 0, &psurfDest);
  626.         hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL, 
  627.             D3DX_FILTER_TRIANGLE, 0);
  628.         ReleasePpo(&psurfSrc);
  629.         ReleasePpo(&psurfDest);
  630.         hr = pcubetex->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_Y, 0, &psurfSrc);
  631.         hr = pcubetexNew->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_Y, 0, &psurfDest);
  632.         hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL, 
  633.             D3DX_FILTER_TRIANGLE, 0);
  634.         ReleasePpo(&psurfSrc);
  635.         ReleasePpo(&psurfDest);
  636.         hr = pcubetex->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_Z, 0, &psurfSrc);
  637.         hr = pcubetexNew->GetCubeMapSurface(D3DCUBEMAP_FACE_POSITIVE_Z, 0, &psurfDest);
  638.         hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL, 
  639.             D3DX_FILTER_TRIANGLE, 0);
  640.         ReleasePpo(&psurfSrc);
  641.         ReleasePpo(&psurfDest);
  642.         hr = pcubetex->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_Z, 0, &psurfSrc);
  643.         hr = pcubetexNew->GetCubeMapSurface(D3DCUBEMAP_FACE_NEGATIVE_Z, 0, &psurfDest);
  644.         hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, psurfSrc, NULL, NULL, 
  645.             D3DX_FILTER_TRIANGLE, 0);
  646.         ReleasePpo(&psurfSrc);
  647.         ReleasePpo(&psurfDest);
  648.         hr = D3DXFilterCubeTexture(pcubetexNew, NULL, 0, D3DX_FILTER_TRIANGLE);
  649.     }
  650.  
  651.     ReleasePpo(&m_ptexOrig);
  652.     if (pvoltexNew != NULL)
  653.         m_ptexOrig = pvoltexNew;
  654.     else if (pcubetexNew != NULL)
  655.         m_ptexOrig = pcubetexNew;
  656.     else
  657.         m_ptexOrig = pmiptexNew;
  658.  
  659.     if (m_ptexNew != NULL)
  660.     {
  661.         // Rather than filtering down the (probably-compressed) m_ptexNew 
  662.         // top level, compress each mip level from the (probably-uncompressed)
  663.         // m_ptexOrig levels.
  664.         if (pvoltexNew != NULL)
  665.         {
  666.             D3DVOLUME_DESC vd;
  667.             ((LPDIRECT3DVOLUMETEXTURE9)m_ptexNew)->GetLevelDesc(0, &vd);
  668.             fmt = vd.Format;
  669.         }
  670.         else if (pcubetexNew != NULL)
  671.         {
  672.             D3DSURFACE_DESC sd;
  673.             ((LPDIRECT3DTEXTURE9)m_ptexNew)->GetLevelDesc(0, &sd);
  674.             fmt = sd.Format;
  675.         }
  676.         else
  677.         {
  678.             D3DSURFACE_DESC sd;
  679.             ((LPDIRECT3DCUBETEXTURE9)m_ptexNew)->GetLevelDesc(0, &sd);
  680.             fmt = sd.Format;
  681.         }
  682.         Compress(fmt, FALSE);
  683.     }
  684.  
  685.     m_bTitleModsChanged = TRUE; // Generate title bar update
  686.     UpdateAllViews(NULL, 1); // tell CView to pick up new surface pointers
  687.     SetModifiedFlag();
  688.     return;
  689.  
  690. LFail:
  691.     ReleasePpo(&pddsNew);
  692. }
  693.  
  694.  
  695. void CDxtexDoc::SetPathName(LPCTSTR lpszPathName, BOOL bAddToMRU) 
  696. {
  697.     CDocument::SetPathName(lpszPathName, bAddToMRU);
  698.  
  699.     DWORD lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
  700.     TCHAR* pszLeaf = strrchr(lpszPathName, '\\');
  701.     if( pszLeaf )
  702.     {
  703.         pszLeaf++;
  704.         TCHAR* pszExtension = strrchr(lpszPathName, '.');
  705.         if( pszExtension && 
  706.             CompareString( lcid, NORM_IGNORECASE, pszExtension, -1, TEXT(".dds"), -1 ) != CSTR_EQUAL )
  707.         {
  708.             lstrcpy(pszExtension, "");
  709.             SetModifiedFlag(TRUE);
  710.             SetTitle(pszLeaf);
  711.             m_strPathName.Empty();
  712.         }
  713.     }
  714. }
  715.  
  716. DWORD CDxtexDoc::NumMips(VOID)
  717. {
  718.     return m_numMips;
  719. }
  720.  
  721.  
  722. void CDxtexDoc::OnFileOpenAlpha() 
  723. {
  724.     HRESULT hr;
  725.     CString fileName;
  726.     LPDIRECT3DTEXTURE9 pmiptex;
  727.  
  728.     if (IsCubeMap() || IsVolumeMap())
  729.         return;
  730.  
  731.     // Premultiplied-alpha files don't support this feature:
  732.     D3DSURFACE_DESC sd;
  733.     ((LPDIRECT3DTEXTURE9)m_ptexOrig)->GetLevelDesc(0, &sd);
  734.     if (sd.Format == D3DFMT_DXT2 || sd.Format == D3DFMT_DXT4)
  735.     {
  736.         AfxMessageBox(ID_ERROR_PREMULTALPHA);
  737.         return;
  738.     }
  739.  
  740.     // Check if the original has alpha
  741.     if( !FormatContainsAlpha(sd.Format)  )
  742.     {
  743.         // If it doesn't then see if the new does
  744.         if (m_ptexNew != NULL)
  745.         {
  746.             ((LPDIRECT3DTEXTURE9)m_ptexNew)->GetLevelDesc(0, &sd);
  747.             if( !FormatContainsAlpha(sd.Format) )
  748.             {
  749.                 AfxMessageBox(ID_ERROR_NEEDALPHA);
  750.                 return;
  751.             }
  752.             else
  753.             {
  754.                 ReleasePpo(&m_ptexOrig);
  755.                 m_ptexOrig = m_ptexNew;
  756.                 m_ptexNew  = NULL;
  757.                 if( AfxGetMainWnd() != NULL )
  758.                     AfxGetMainWnd()->PostMessage(WM_COMMAND, ID_VIEW_ORIGINAL, 0);
  759.             }
  760.         }
  761.         else
  762.         {
  763.                 AfxMessageBox(ID_ERROR_NEEDALPHA);
  764.                 return;
  765.         }
  766.     }
  767.  
  768.     pmiptex = (LPDIRECT3DTEXTURE9)m_ptexOrig;
  769.  
  770.     if (!PromptForBmp(&fileName))
  771.         return;
  772.  
  773.     LPDIRECT3DSURFACE9 psurf;
  774.     if (FAILED(hr = pmiptex->GetSurfaceLevel(0, &psurf)))
  775.         return;
  776.  
  777.     if (FAILED(hr = LoadAlphaIntoSurface(fileName, psurf)))
  778.         return;
  779.     if (m_numMips > 1)
  780.         OnGenerateMipMaps();
  781.     else if (m_ptexNew != NULL)
  782.     {
  783.         ((LPDIRECT3DTEXTURE9)m_ptexNew)->GetLevelDesc(0, &sd);
  784.         Compress(sd.Format, FALSE);
  785.     }
  786.     UpdateAllViews(NULL, 1);
  787. }
  788.  
  789.  
  790. HRESULT CDxtexDoc::LoadAlphaIntoSurface(CString& strPath, LPDIRECT3DSURFACE9 psurf)
  791. {
  792.     HRESULT hr;
  793.     D3DSURFACE_DESC sd;
  794.     LPDIRECT3DDEVICE9 pd3ddev = PDxtexApp()->Pd3ddev();
  795.     LPDIRECT3DTEXTURE9 ptexAlpha;
  796.     LPDIRECT3DSURFACE9 psurfAlpha;
  797.     LPDIRECT3DSURFACE9 psurfTarget;
  798.  
  799.     psurf->GetDesc(&sd);
  800.  
  801.     // Load the alpha BMP into psurfAlpha, a new A8R8G8B8 surface
  802.     hr = D3DXCreateTextureFromFileEx(pd3ddev, strPath, sd.Width, sd.Height, 1, 0, 
  803.         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_FILTER_TRIANGLE, 
  804.         D3DX_FILTER_TRIANGLE, 0, NULL, NULL, &ptexAlpha);
  805.     hr = ptexAlpha->GetSurfaceLevel(0, &psurfAlpha);
  806.  
  807.     // Copy the target surface into an A8R8G8B8 surface
  808.     hr = pd3ddev->CreateOffscreenPlainSurface(sd.Width, sd.Height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &psurfTarget, NULL);
  809.     hr = D3DXLoadSurfaceFromSurface(psurfTarget, NULL, NULL, psurf, NULL, NULL, 
  810.         D3DX_FILTER_TRIANGLE, 0);
  811.  
  812.     // Fill in the alpha channels of psurfTarget based on the blue channel of psurfAlpha
  813.     D3DLOCKED_RECT lrSrc;
  814.     D3DLOCKED_RECT lrDest;
  815.  
  816.     hr = psurfAlpha->LockRect(&lrSrc, NULL, D3DLOCK_READONLY);
  817.     hr = psurfTarget->LockRect(&lrDest, NULL, 0);
  818.  
  819.     DWORD xp;
  820.     DWORD yp;
  821.     DWORD* pdwRowSrc = (DWORD*)lrSrc.pBits;
  822.     DWORD* pdwRowDest = (DWORD*)lrDest.pBits;
  823.     DWORD* pdwSrc;
  824.     DWORD* pdwDest;
  825.     DWORD dwAlpha;
  826.     LONG dataBytesPerRow = 4 * sd.Width;
  827.  
  828.     for (yp = 0; yp < sd.Height; yp++)
  829.     {
  830.         pdwSrc = pdwRowSrc;
  831.         pdwDest = pdwRowDest;
  832.         for (xp = 0; xp < sd.Width; xp++)
  833.         {
  834.             dwAlpha = *pdwSrc << 24;
  835.             *pdwDest &= 0x00ffffff;
  836.             *pdwDest |= dwAlpha;
  837.  
  838.             pdwSrc++;
  839.             pdwDest++;
  840.         }
  841.         pdwRowSrc += lrSrc.Pitch / 4;
  842.         pdwRowDest += lrDest.Pitch / 4;
  843.     }
  844.  
  845.     psurfAlpha->UnlockRect();
  846.     psurfTarget->UnlockRect();
  847.  
  848.     // Copy psurfTarget back into real surface
  849.     hr = D3DXLoadSurfaceFromSurface(psurf, NULL, NULL, psurfTarget, NULL, NULL, 
  850.         D3DX_FILTER_TRIANGLE, 0);
  851.     
  852.     // Release allocated interfaces
  853.     ReleasePpo(&psurfTarget);
  854.     ReleasePpo(&psurfAlpha);
  855.     ReleasePpo(&ptexAlpha);
  856.  
  857.     return S_OK;
  858. }
  859.  
  860.  
  861. BOOL CDxtexDoc::PromptForBmp(CString* pstrPath)
  862. {
  863.     CFileDialog dlgFile(TRUE);
  864.  
  865.     CString title;
  866.     VERIFY(title.LoadString(AFX_IDS_OPENFILE));
  867.  
  868.     CString strFilter;
  869.     CString strDefault;
  870.  
  871.     strFilter += "Image Files (*.dds, *.hdr, *.bmp, *.tga, *.jpg, *.png, *.dib)";
  872.     strFilter += (TCHAR)'\0';   // next string please
  873.     strFilter += _T("*.dds;*.hdr;*.bmp;*.tga;*.jpg;*.png;*.dib");
  874.     strFilter += (TCHAR)'\0';   // last string
  875.     dlgFile.m_ofn.nMaxCustFilter++;
  876.  
  877.     // append the "*.*" all files filter
  878.     CString allFilter;
  879.     VERIFY(allFilter.LoadString(AFX_IDS_ALLFILTER));
  880.     strFilter += allFilter;
  881.     strFilter += (TCHAR)'\0';   // next string please
  882.     strFilter += _T("*.*");
  883.     strFilter += (TCHAR)'\0';   // last string
  884.     dlgFile.m_ofn.nMaxCustFilter++;
  885.  
  886.     dlgFile.m_ofn.lpstrFilter = strFilter;
  887.     dlgFile.m_ofn.lpstrTitle = title;
  888.     dlgFile.m_ofn.lpstrFile = pstrPath->GetBuffer(_MAX_PATH);
  889.  
  890.     INT_PTR nResult = dlgFile.DoModal();
  891.     pstrPath->ReleaseBuffer();
  892.     if (nResult != IDOK)
  893.         return FALSE;
  894.     return TRUE;
  895. }
  896.  
  897.  
  898. void CDxtexDoc::OpenSubsurface(D3DCUBEMAP_FACES FaceType, LONG lwMip, LONG lwSlice)
  899. {
  900.     HRESULT hr;
  901.     CString fileName;
  902.     LPDIRECT3DDEVICE9 pd3ddev = PDxtexApp()->Pd3ddev();
  903.     LPDIRECT3DTEXTURE9 ptex = NULL;
  904.     LPDIRECT3DSURFACE9 psurfOrig = NULL;
  905.     LPDIRECT3DSURFACE9 psurfNew = NULL;
  906.  
  907.     if (!PromptForBmp(&fileName))
  908.         return;
  909.  
  910.     if (IsVolumeMap())
  911.     {
  912.         hr = D3DXCreateTextureFromFile(pd3ddev, fileName, &ptex);
  913.         hr = ptex->GetSurfaceLevel(0, &psurfOrig);
  914.     }
  915.     else if (IsCubeMap())
  916.     {
  917.         hr = ((LPDIRECT3DCUBETEXTURE9)m_ptexOrig)->GetCubeMapSurface(FaceType, lwMip, &psurfOrig);
  918.         if (m_ptexNew != NULL)
  919.             hr = ((LPDIRECT3DCUBETEXTURE9)m_ptexNew)->GetCubeMapSurface(FaceType, lwMip, &psurfNew);
  920.         hr = D3DXLoadSurfaceFromFile(psurfOrig, NULL, NULL, fileName, NULL, D3DX_FILTER_TRIANGLE, 0, NULL);
  921.     }
  922.     else
  923.     {
  924.         hr = ((LPDIRECT3DTEXTURE9)m_ptexOrig)->GetSurfaceLevel(lwMip, &psurfOrig);
  925.         if (m_ptexNew != NULL)
  926.             hr = ((LPDIRECT3DTEXTURE9)m_ptexNew)->GetSurfaceLevel(lwMip, &psurfNew);
  927.         hr = D3DXLoadSurfaceFromFile(psurfOrig, NULL, NULL, fileName, NULL, D3DX_FILTER_TRIANGLE, 0, NULL);
  928.     }
  929.  
  930.     // Look for "foo_a.bmp" for alpha channel
  931.     int i = fileName.ReverseFind('.');
  932.     fileName = fileName.Left(i) + "_a.bmp";
  933.     CFileStatus status;
  934.     if (CFile::GetStatus(fileName, status))
  935.     {
  936.         if (FAILED(hr = LoadAlphaIntoSurface(fileName, psurfOrig)))
  937.             return;
  938.     }
  939.  
  940.     if (IsVolumeMap())
  941.     {
  942.         LPDIRECT3DVOLUME9 pvol;
  943.         hr = ((LPDIRECT3DVOLUMETEXTURE9)m_ptexOrig)->GetVolumeLevel(lwMip, &pvol);
  944.         hr = LoadVolumeSliceFromSurface(pvol, lwSlice, psurfOrig);
  945.         ReleasePpo(&pvol);
  946.         if (m_ptexNew)
  947.         {
  948.             hr = ((LPDIRECT3DVOLUMETEXTURE9)m_ptexNew)->GetVolumeLevel(lwMip, &pvol);
  949.             hr = LoadVolumeSliceFromSurface(pvol, lwSlice, psurfOrig);
  950.             ReleasePpo(&pvol);
  951.         }
  952.     }
  953.     else if (psurfNew != NULL)
  954.     {
  955.         hr = D3DXLoadSurfaceFromSurface(psurfNew, NULL, NULL, psurfOrig, NULL, NULL, D3DX_FILTER_TRIANGLE, 0);
  956.     }
  957.  
  958.     ReleasePpo(&psurfOrig);
  959.     ReleasePpo(&psurfNew);
  960.     ReleasePpo(&ptex);
  961.  
  962.     SetModifiedFlag(TRUE);
  963.     UpdateAllViews(NULL, 1);
  964. }
  965.  
  966.  
  967. void CDxtexDoc::OpenAlphaSubsurface(D3DCUBEMAP_FACES FaceType, LONG lwMip, LONG lwSlice)
  968. {
  969.     HRESULT hr;
  970.     CString fileName;
  971.     LPDIRECT3DDEVICE9 pd3ddev = PDxtexApp()->Pd3ddev();
  972.     LPDIRECT3DTEXTURE9 ptexOrig = NULL;
  973.     LPDIRECT3DTEXTURE9 ptexNew = NULL;
  974.     LPDIRECT3DSURFACE9 psurfOrig = NULL;
  975.     LPDIRECT3DSURFACE9 psurfNew = NULL;
  976.     LPDIRECT3DVOLUME9 pvolOrig = NULL;
  977.     LPDIRECT3DVOLUME9 pvolNew = NULL;
  978.     D3DSURFACE_DESC sd;
  979.     DWORD dwWidth = m_dwWidth;
  980.     DWORD dwHeight = m_dwHeight;
  981.  
  982.     if (IsVolumeMap())
  983.     {
  984.         for (int i = 0; i < lwMip; i++)
  985.         {
  986.             dwWidth /= 2;
  987.             dwHeight /= 2;
  988.         }
  989.         hr = pd3ddev->CreateTexture(dwWidth, dwHeight, 1, 
  990.              0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &ptexOrig, NULL);
  991.         hr = ptexOrig->GetSurfaceLevel(0, &psurfOrig);
  992.         hr = ((LPDIRECT3DVOLUMETEXTURE9)m_ptexOrig)->GetVolumeLevel(lwMip, &pvolOrig);
  993.         hr = LoadSurfaceFromVolumeSlice(pvolOrig, lwSlice, psurfOrig);
  994.         if (m_ptexNew != NULL)
  995.         {
  996.             hr = pd3ddev->CreateTexture(dwWidth, dwHeight, 1, 
  997.                  0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &ptexNew, NULL);
  998.             hr = ptexNew->GetSurfaceLevel(0, &psurfOrig);
  999.             hr = ((LPDIRECT3DVOLUMETEXTURE9)m_ptexOrig)->GetVolumeLevel(lwMip, &pvolNew);
  1000.             hr = LoadSurfaceFromVolumeSlice(pvolNew, lwSlice, psurfOrig);
  1001.         }
  1002.     }
  1003.     else if (IsCubeMap())
  1004.     {
  1005.         hr = ((LPDIRECT3DCUBETEXTURE9)m_ptexOrig)->GetCubeMapSurface(FaceType, lwMip, &psurfOrig);
  1006.         ((LPDIRECT3DCUBETEXTURE9)m_ptexOrig)->GetLevelDesc(lwMip, &sd);
  1007.         if (sd.Format == D3DFMT_DXT2 || sd.Format == D3DFMT_DXT4)
  1008.         {
  1009.             AfxMessageBox(ID_ERROR_PREMULTALPHA);
  1010.             goto LCleanup;
  1011.         }
  1012.         if (m_ptexNew != NULL)
  1013.         {
  1014.             hr = ((LPDIRECT3DCUBETEXTURE9)m_ptexNew)->GetCubeMapSurface(FaceType, lwMip, &psurfNew);
  1015.             ((LPDIRECT3DCUBETEXTURE9)m_ptexNew)->GetLevelDesc(lwMip, &sd);
  1016.             if (sd.Format == D3DFMT_DXT2 || sd.Format == D3DFMT_DXT4)
  1017.             {
  1018.                 AfxMessageBox(ID_ERROR_PREMULTALPHA);
  1019.                 goto LCleanup;
  1020.             }
  1021.         }
  1022.     }
  1023.     else
  1024.     {
  1025.         BOOL bAlphaFound = FALSE;
  1026.         hr = ((LPDIRECT3DTEXTURE9)m_ptexOrig)->GetSurfaceLevel(lwMip, &psurfOrig);
  1027.         ((LPDIRECT3DTEXTURE9)m_ptexOrig)->GetLevelDesc(lwMip, &sd);
  1028.         if (sd.Format == D3DFMT_DXT2 || sd.Format == D3DFMT_DXT4)
  1029.         {
  1030.             AfxMessageBox(ID_ERROR_PREMULTALPHA);
  1031.             goto LCleanup;
  1032.         }
  1033.  
  1034.         // Check if the original has alpha
  1035.         if( FormatContainsAlpha(sd.Format) )
  1036.         {
  1037.             bAlphaFound = TRUE;
  1038.         }
  1039.  
  1040.         if (m_ptexNew != NULL)
  1041.         {
  1042.             hr = ((LPDIRECT3DTEXTURE9)m_ptexNew)->GetSurfaceLevel(lwMip, &psurfNew);
  1043.             ((LPDIRECT3DTEXTURE9)m_ptexNew)->GetLevelDesc(lwMip, &sd);
  1044.             if (sd.Format == D3DFMT_DXT2 || sd.Format == D3DFMT_DXT4)
  1045.             {
  1046.                 AfxMessageBox(ID_ERROR_PREMULTALPHA);
  1047.                 goto LCleanup;
  1048.             }
  1049.             // Check if the new has alpha
  1050.             if( FormatContainsAlpha(sd.Format) )
  1051.             {
  1052.                 bAlphaFound = TRUE;
  1053.             }
  1054.         }
  1055.  
  1056.         if( bAlphaFound == FALSE )
  1057.         {
  1058.             AfxMessageBox(ID_ERROR_NEEDALPHA);
  1059.             goto LCleanup;
  1060.         }
  1061.     }
  1062.  
  1063.     if (!PromptForBmp(&fileName))
  1064.         goto LCleanup;
  1065.  
  1066.     if (FAILED(hr = LoadAlphaIntoSurface(fileName, psurfOrig)))
  1067.         goto LCleanup;
  1068.  
  1069.     if (psurfNew != NULL)
  1070.     {
  1071.         if (FAILED(hr = LoadAlphaIntoSurface(fileName, psurfNew)))
  1072.             goto LCleanup;
  1073.     }
  1074.  
  1075.     if (pvolOrig != NULL)
  1076.     {
  1077.         hr = LoadVolumeSliceFromSurface(pvolOrig, lwSlice, psurfOrig);
  1078.     }
  1079.     if (pvolNew != NULL)
  1080.     {
  1081.         hr = LoadVolumeSliceFromSurface(pvolNew, lwSlice, psurfNew);
  1082.     }
  1083.  
  1084.     SetModifiedFlag(TRUE);
  1085.     UpdateAllViews(NULL, 1);
  1086.  
  1087. LCleanup:
  1088.     ReleasePpo(&psurfOrig);
  1089.     ReleasePpo(&psurfNew);
  1090.     ReleasePpo(&ptexOrig);
  1091.     ReleasePpo(&ptexNew);
  1092.     ReleasePpo(&pvolOrig);
  1093.     ReleasePpo(&pvolNew);
  1094. }
  1095.  
  1096.  
  1097. void CDxtexDoc::OnFormatChangeCubeMapFaces() 
  1098. {
  1099.     HRESULT hr;
  1100.     LPDIRECT3DDEVICE9 pd3ddev = PDxtexApp()->Pd3ddev();
  1101.     D3DSURFACE_DESC sd;
  1102.     LPDIRECT3DCUBETEXTURE9 ptexCube;
  1103.     DWORD iLevel;
  1104.     LPDIRECT3DSURFACE9 psurfSrc;
  1105.     LPDIRECT3DSURFACE9 psurfDest;
  1106.  
  1107.     CCubeMapDlg cubeMapDlg;
  1108.     if (IDCANCEL == cubeMapDlg.DoModal())
  1109.         return;
  1110.     
  1111.     // Change m_ptexOrig into a cubemap
  1112.     ((LPDIRECT3DTEXTURE9)m_ptexOrig)->GetLevelDesc(0, &sd);
  1113.     hr = D3DXCreateCubeTexture(pd3ddev, m_dwWidth, m_numMips, 0, sd.Format, D3DPOOL_MANAGED, &ptexCube);
  1114.     for (iLevel = 0; iLevel < m_numMips; iLevel++)
  1115.     {
  1116.         hr = ((LPDIRECT3DTEXTURE9)m_ptexOrig)->GetSurfaceLevel(iLevel, &psurfSrc);
  1117.         hr = ptexCube->GetCubeMapSurface((D3DCUBEMAP_FACES)cubeMapDlg.m_iFace, iLevel, &psurfDest);
  1118.         hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, 
  1119.             psurfSrc, NULL, NULL, D3DX_FILTER_TRIANGLE, 0);
  1120.         ReleasePpo(&psurfSrc);
  1121.         ReleasePpo(&psurfDest);
  1122.     }
  1123.     ReleasePpo(&m_ptexOrig);
  1124.     m_ptexOrig = ptexCube;
  1125.  
  1126.     // Change m_ptexNew into a cubemap too
  1127.     if (m_ptexNew != NULL)
  1128.     {
  1129.         ((LPDIRECT3DTEXTURE9)m_ptexNew)->GetLevelDesc(0, &sd);
  1130.         hr = D3DXCreateCubeTexture(pd3ddev, m_dwWidth, m_numMips, 0, sd.Format, D3DPOOL_MANAGED, &ptexCube);
  1131.         for (iLevel = 0; iLevel < m_numMips; iLevel++)
  1132.         {
  1133.             hr = ((LPDIRECT3DTEXTURE9)m_ptexNew)->GetSurfaceLevel(iLevel, &psurfSrc);
  1134.             hr = ptexCube->GetCubeMapSurface((D3DCUBEMAP_FACES)cubeMapDlg.m_iFace, iLevel, &psurfDest);
  1135.             hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, 
  1136.                 psurfSrc, NULL, NULL, D3DX_FILTER_TRIANGLE, 0);
  1137.             ReleasePpo(&psurfSrc);
  1138.             ReleasePpo(&psurfDest);
  1139.         }
  1140.         ReleasePpo(&m_ptexNew);
  1141.         m_ptexNew = ptexCube;
  1142.     }
  1143.     m_dwCubeMapFlags = DDS_CUBEMAP_ALLFACES;
  1144.     SetModifiedFlag();
  1145.     UpdateAllViews(NULL, 1); // tell CView to pick up new surface pointers
  1146. }
  1147.  
  1148.  
  1149. void CDxtexDoc::OnFormatMakeIntoVolumeMap() 
  1150. {
  1151.     HRESULT hr;
  1152.     LPDIRECT3DDEVICE9 pd3ddev = PDxtexApp()->Pd3ddev();
  1153.     D3DSURFACE_DESC sd;
  1154.     LPDIRECT3DVOLUMETEXTURE9 ptexVolume;
  1155.     DWORD iLevel;
  1156.     LPDIRECT3DSURFACE9 psurfSrc;
  1157.     LPDIRECT3DVOLUME9 pvolumeDest;
  1158.     UINT numLayers;
  1159.  
  1160.     CVolumeMapDlg volumeMapDlg;
  1161.     if (IDCANCEL == volumeMapDlg.DoModal())
  1162.         return;
  1163.  
  1164.     numLayers = (1 << volumeMapDlg.m_powLayers) * 2;
  1165.  
  1166.     // Change m_ptexOrig into a volumemap
  1167.     ((LPDIRECT3DTEXTURE9)m_ptexOrig)->GetLevelDesc(0, &sd);
  1168.     hr = pd3ddev->CreateVolumeTexture(m_dwWidth, m_dwHeight, numLayers,
  1169.         m_numMips, 0, sd.Format, D3DPOOL_SYSTEMMEM, &ptexVolume, NULL);
  1170.     if (FAILED(hr))
  1171.     {
  1172.         if( E_OUTOFMEMORY == hr )
  1173.             AfxMessageBox( ID_ERROR_OUTOFMEMORY );
  1174.         else
  1175.             AfxMessageBox( ID_ERROR_UNKNOWN );
  1176.         return;
  1177.     }
  1178.     for (iLevel = 0; iLevel < m_numMips; iLevel++)
  1179.     {
  1180.         hr = ((LPDIRECT3DTEXTURE9)m_ptexOrig)->GetSurfaceLevel(iLevel, &psurfSrc);
  1181.         hr = ptexVolume->GetVolumeLevel(iLevel, &pvolumeDest);
  1182.         hr = LoadVolumeSliceFromSurface(pvolumeDest, 0, psurfSrc);
  1183.         ReleasePpo(&psurfSrc);
  1184.         ReleasePpo(&pvolumeDest);
  1185.     }
  1186.     ReleasePpo(&m_ptexOrig);
  1187.     m_ptexOrig = ptexVolume;
  1188.  
  1189.     // Change m_ptexNew into a volumemap too
  1190.     if (m_ptexNew != NULL)
  1191.     {
  1192.         ((LPDIRECT3DTEXTURE9)m_ptexNew)->GetLevelDesc(0, &sd);
  1193.         hr = pd3ddev->CreateVolumeTexture(m_dwWidth, m_dwHeight, numLayers,
  1194.             m_numMips, 0, sd.Format, D3DPOOL_SYSTEMMEM, &ptexVolume, NULL);
  1195.         if (FAILED(hr))
  1196.             return;
  1197.         for (iLevel = 0; iLevel < m_numMips; iLevel++)
  1198.         {
  1199.             hr = ((LPDIRECT3DTEXTURE9)m_ptexNew)->GetSurfaceLevel(iLevel, &psurfSrc);
  1200.             hr = ptexVolume->GetVolumeLevel(iLevel, &pvolumeDest);
  1201.             hr = LoadVolumeSliceFromSurface(pvolumeDest, 0, psurfSrc);
  1202.             ReleasePpo(&psurfSrc);
  1203.             ReleasePpo(&pvolumeDest);
  1204.         }
  1205.         ReleasePpo(&m_ptexNew);
  1206.         m_ptexNew = ptexVolume;
  1207.     }
  1208.     m_dwDepth = numLayers;
  1209.     SetModifiedFlag();
  1210.     UpdateAllViews(NULL, 1); // tell CView to pick up new surface pointers
  1211. }
  1212.  
  1213.  
  1214. HRESULT CDxtexDoc::LoadVolumeSliceFromSurface(LPDIRECT3DVOLUME9 pVolume, UINT iSlice, LPDIRECT3DSURFACE9 psurf)
  1215. {
  1216.     HRESULT hr;
  1217.     D3DSURFACE_DESC sd;
  1218.     D3DVOLUME_DESC vd;
  1219.     D3DLOCKED_RECT lr;
  1220.     D3DBOX boxSrc;
  1221.     D3DBOX boxDest;
  1222.  
  1223.     psurf->GetDesc(&sd);
  1224.     pVolume->GetDesc(&vd);
  1225.  
  1226.     boxSrc.Left = 0;
  1227.     boxSrc.Right = sd.Width;
  1228.     boxSrc.Top = 0;
  1229.     boxSrc.Bottom = sd.Height;
  1230.     boxSrc.Front = 0;
  1231.     boxSrc.Back = 1;
  1232.  
  1233.     boxDest.Left = 0;
  1234.     boxDest.Right = vd.Width;
  1235.     boxDest.Top = 0;
  1236.     boxDest.Bottom = vd.Height;
  1237.     boxDest.Front = iSlice;
  1238.     boxDest.Back = iSlice + 1;
  1239.  
  1240.     hr = psurf->LockRect(&lr, NULL, 0);
  1241.     if (FAILED(hr))
  1242.         return hr;
  1243.  
  1244.     hr = D3DXLoadVolumeFromMemory(pVolume, NULL, &boxDest, lr.pBits, sd.Format, lr.Pitch, 
  1245.         0, NULL, &boxSrc, D3DX_FILTER_TRIANGLE, 0);
  1246.  
  1247.     psurf->UnlockRect();
  1248.  
  1249.     return hr;
  1250. }
  1251.  
  1252.  
  1253. HRESULT CDxtexDoc::LoadSurfaceFromVolumeSlice(LPDIRECT3DVOLUME9 pVolume, UINT iSlice, LPDIRECT3DSURFACE9 psurf)
  1254. {
  1255.     HRESULT hr;
  1256.     D3DVOLUME_DESC vd;
  1257.     D3DLOCKED_BOX lb;
  1258.     D3DBOX box;
  1259.     RECT rc;
  1260.  
  1261.     pVolume->GetDesc(&vd);
  1262.  
  1263.     box.Left = 0;
  1264.     box.Right = vd.Width;
  1265.     box.Top = 0;
  1266.     box.Bottom = vd.Height;
  1267.     box.Front = iSlice;
  1268.     box.Back = iSlice + 1;
  1269.  
  1270.     rc.left = 0;
  1271.     rc.right = vd.Width;
  1272.     rc.top = 0;
  1273.     rc.bottom = vd.Height;
  1274.  
  1275.     hr = pVolume->LockBox(&lb, &box, 0);
  1276.     if (FAILED(hr))
  1277.         return hr;
  1278.  
  1279.     hr = D3DXLoadSurfaceFromMemory(psurf, NULL, NULL, lb.pBits, vd.Format, lb.RowPitch, 
  1280.         NULL, &rc, D3DX_FILTER_TRIANGLE, 0);
  1281.  
  1282.     pVolume->UnlockBox();
  1283.  
  1284.     return hr;
  1285. }
  1286.  
  1287.  
  1288. HRESULT CDxtexDoc::BltAllLevels(D3DCUBEMAP_FACES FaceType, 
  1289.     LPDIRECT3DBASETEXTURE9 ptexSrc, LPDIRECT3DBASETEXTURE9 ptexDest)
  1290. {
  1291.     HRESULT hr;
  1292.     LPDIRECT3DTEXTURE9 pmiptexSrc;
  1293.     LPDIRECT3DTEXTURE9 pmiptexDest;
  1294.     LPDIRECT3DCUBETEXTURE9 pcubetexSrc;
  1295.     LPDIRECT3DCUBETEXTURE9 pcubetexDest;
  1296.     LPDIRECT3DVOLUMETEXTURE9 pvoltexSrc;
  1297.     LPDIRECT3DVOLUMETEXTURE9 pvoltexDest;
  1298.     DWORD iLevel;
  1299.  
  1300.     if (IsVolumeMap())
  1301.     {
  1302.         pvoltexSrc = (LPDIRECT3DVOLUMETEXTURE9)ptexSrc;
  1303.         pvoltexDest = (LPDIRECT3DVOLUMETEXTURE9)ptexDest;
  1304.     }
  1305.     else if (IsCubeMap())
  1306.     {
  1307.         pcubetexSrc = (LPDIRECT3DCUBETEXTURE9)ptexSrc;
  1308.         pcubetexDest = (LPDIRECT3DCUBETEXTURE9)ptexDest;
  1309.     }
  1310.     else
  1311.     {
  1312.         pmiptexSrc = (LPDIRECT3DTEXTURE9)ptexSrc;
  1313.         pmiptexDest = (LPDIRECT3DTEXTURE9)ptexDest;
  1314.     }
  1315.  
  1316.     for (iLevel = 0; iLevel < m_numMips; iLevel++)
  1317.     {
  1318.         if (IsVolumeMap())
  1319.         {
  1320.             LPDIRECT3DVOLUME9 pvolSrc = NULL;
  1321.             LPDIRECT3DVOLUME9 pvolDest = NULL;
  1322.             hr = pvoltexSrc->GetVolumeLevel(iLevel, &pvolSrc);
  1323.             hr = pvoltexDest->GetVolumeLevel(iLevel, &pvolDest);
  1324.             hr = D3DXLoadVolumeFromVolume(pvolDest, NULL, NULL, 
  1325.                 pvolSrc, NULL, NULL, D3DX_FILTER_TRIANGLE, 0);
  1326.             ReleasePpo(&pvolSrc);
  1327.             ReleasePpo(&pvolDest);
  1328.         }
  1329.         else if (IsCubeMap())
  1330.         {
  1331.             LPDIRECT3DSURFACE9 psurfSrc = NULL;
  1332.             LPDIRECT3DSURFACE9 psurfDest = NULL;
  1333.             hr = pcubetexSrc->GetCubeMapSurface(FaceType, iLevel, &psurfSrc);
  1334.             hr = pcubetexDest->GetCubeMapSurface(FaceType, iLevel, &psurfDest);
  1335.             hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, 
  1336.                 psurfSrc, NULL, NULL, D3DX_FILTER_TRIANGLE, 0);
  1337.             ReleasePpo(&psurfSrc);
  1338.             ReleasePpo(&psurfDest);
  1339.         }
  1340.         else
  1341.         {
  1342.             LPDIRECT3DSURFACE9 psurfSrc = NULL;
  1343.             LPDIRECT3DSURFACE9 psurfDest = NULL;
  1344.             hr = pmiptexSrc->GetSurfaceLevel(iLevel, &psurfSrc);
  1345.             hr = pmiptexDest->GetSurfaceLevel(iLevel, &psurfDest);
  1346.             hr = D3DXLoadSurfaceFromSurface(psurfDest, NULL, NULL, 
  1347.                 psurfSrc, NULL, NULL, D3DX_FILTER_TRIANGLE, 0);
  1348.             ReleasePpo(&psurfSrc);
  1349.             ReleasePpo(&psurfDest);
  1350.         }
  1351.     }
  1352.  
  1353.     return S_OK;
  1354. }
  1355.  
  1356.  
  1357. HRESULT CDxtexDoc::Resize(DWORD dwWidthNew, DWORD dwHeightNew)
  1358. {
  1359.     HRESULT hr;
  1360.     LPDIRECT3DTEXTURE9 pmiptexNew;
  1361.     LPDIRECT3DDEVICE9 pd3ddev = PDxtexApp()->Pd3ddev();
  1362.     
  1363.     hr = pd3ddev->CreateTexture(dwWidthNew, dwHeightNew, m_numMips, 
  1364.          0, GetFormat(m_ptexOrig), D3DPOOL_MANAGED, &pmiptexNew, NULL);
  1365.     if (FAILED(hr))
  1366.         return hr;
  1367.     if (FAILED(BltAllLevels(D3DCUBEMAP_FACE_FORCE_DWORD, m_ptexOrig, pmiptexNew)))
  1368.         return hr;
  1369.     ReleasePpo(&m_ptexOrig);
  1370.     m_ptexOrig = pmiptexNew;
  1371.  
  1372.     if( m_ptexNew != NULL )
  1373.     {
  1374.         hr = pd3ddev->CreateTexture(dwWidthNew, dwHeightNew, m_numMips, 
  1375.              0, GetFormat(m_ptexOrig), D3DPOOL_MANAGED, &pmiptexNew, NULL);
  1376.         if (FAILED(hr))
  1377.             return hr;
  1378.         if (FAILED(BltAllLevels(D3DCUBEMAP_FACE_FORCE_DWORD, m_ptexNew, pmiptexNew)))
  1379.             return hr;
  1380.         ReleasePpo(&m_ptexNew);
  1381.         m_ptexNew = pmiptexNew;
  1382.     }
  1383.  
  1384.     m_dwWidth = dwWidthNew;
  1385.     m_dwHeight = dwHeightNew;
  1386.     SetModifiedFlag(TRUE);
  1387.     UpdateAllViews(NULL, 4);
  1388.  
  1389.     return S_OK;
  1390. }
  1391.  
  1392.  
  1393. void CDxtexDoc::OpenCubeFace(D3DCUBEMAP_FACES FaceType)
  1394. {
  1395.     HRESULT hr;
  1396.     CString fileName;
  1397.     LPDIRECT3DSURFACE9 psurfOrig = NULL;
  1398.     LPDIRECT3DSURFACE9 psurfNew = NULL;
  1399.  
  1400.     if (!IsCubeMap())
  1401.         return;
  1402.  
  1403.     hr = ((LPDIRECT3DCUBETEXTURE9)m_ptexOrig)->GetCubeMapSurface(FaceType, 0, &psurfOrig);
  1404.     if (m_ptexNew != NULL)
  1405.         hr = ((LPDIRECT3DCUBETEXTURE9)m_ptexNew)->GetCubeMapSurface(FaceType, 0, &psurfNew);
  1406.  
  1407.     if (!PromptForBmp(&fileName))
  1408.         return;
  1409.  
  1410.     hr = D3DXLoadSurfaceFromFile(psurfOrig, NULL, NULL, fileName, NULL, D3DX_FILTER_TRIANGLE, 0, NULL);
  1411.  
  1412.     // Look for "foo_a.bmp" for alpha channel
  1413.     int i = fileName.ReverseFind('.');
  1414.     fileName = fileName.Left(i) + "_a.bmp";
  1415.     CFileStatus status;
  1416.     if (CFile::GetStatus(fileName, status))
  1417.     {
  1418.         if (FAILED(hr = LoadAlphaIntoSurface(fileName, psurfOrig)))
  1419.             return;
  1420.     }
  1421.  
  1422.     if (m_numMips > 1)
  1423.     {
  1424.         hr = D3DXFilterCubeTexture((LPDIRECT3DCUBETEXTURE9)m_ptexOrig, NULL, 0, D3DX_FILTER_TRIANGLE);
  1425.     }
  1426.  
  1427.  
  1428.     if (psurfNew != NULL)
  1429.     {
  1430.         hr = D3DXLoadSurfaceFromSurface(psurfNew, NULL, NULL, psurfOrig, NULL, NULL, D3DX_FILTER_TRIANGLE, 0);
  1431.  
  1432.         if (m_numMips > 1)
  1433.         {
  1434.             hr = D3DXFilterCubeTexture((LPDIRECT3DCUBETEXTURE9)m_ptexNew, NULL, 0, D3DX_FILTER_TRIANGLE);
  1435.         }
  1436.     }
  1437.  
  1438.     ReleasePpo(&psurfOrig);
  1439.     ReleasePpo(&psurfNew);
  1440.  
  1441.     SetModifiedFlag(TRUE);
  1442.     UpdateAllViews(NULL, 1);
  1443. }
  1444.  
  1445.  
  1446. void CDxtexDoc::OpenAlphaCubeFace(D3DCUBEMAP_FACES FaceType)
  1447. {
  1448.     HRESULT hr;
  1449.     CString fileName;
  1450.     LPDIRECT3DSURFACE9 psurfOrig = NULL;
  1451.     LPDIRECT3DSURFACE9 psurfNew = NULL;
  1452.     D3DSURFACE_DESC sd;
  1453.  
  1454.     if (!IsCubeMap())
  1455.         return;
  1456.  
  1457.     hr = ((LPDIRECT3DCUBETEXTURE9)m_ptexOrig)->GetCubeMapSurface(FaceType, 0, &psurfOrig);
  1458.     ((LPDIRECT3DCUBETEXTURE9)m_ptexOrig)->GetLevelDesc(0, &sd);
  1459.     if (sd.Format == D3DFMT_DXT2 || sd.Format == D3DFMT_DXT4)
  1460.     {
  1461.         AfxMessageBox(ID_ERROR_PREMULTALPHA);
  1462.         return;
  1463.     }
  1464.     if (m_ptexNew != NULL)
  1465.     {
  1466.         hr = ((LPDIRECT3DCUBETEXTURE9)m_ptexNew)->GetCubeMapSurface(FaceType, 0, &psurfNew);
  1467.     }
  1468.  
  1469.     if (!PromptForBmp(&fileName))
  1470.         return;
  1471.  
  1472.     if (FAILED(hr = LoadAlphaIntoSurface(fileName, psurfOrig)))
  1473.         return;
  1474.  
  1475.     if (psurfNew != NULL)
  1476.     {
  1477.         if (FAILED(hr = LoadAlphaIntoSurface(fileName, psurfNew)))
  1478.             return;
  1479.     }
  1480.  
  1481.     if (m_numMips > 1)
  1482.     {
  1483.         hr = D3DXFilterCubeTexture((LPDIRECT3DCUBETEXTURE9)m_ptexOrig, NULL, 0, D3DX_FILTER_TRIANGLE);
  1484.     }
  1485.  
  1486.  
  1487.     if (psurfNew != NULL)
  1488.     {
  1489.         hr = D3DXLoadSurfaceFromSurface(psurfNew, NULL, NULL, psurfOrig, NULL, NULL, D3DX_FILTER_TRIANGLE, 0);
  1490.  
  1491.         if (m_numMips > 1)
  1492.         {
  1493.             hr = D3DXFilterCubeTexture((LPDIRECT3DCUBETEXTURE9)m_ptexNew, NULL, 0, D3DX_FILTER_TRIANGLE);
  1494.         }
  1495.     }
  1496.  
  1497.     ReleasePpo(&psurfOrig);
  1498.     ReleasePpo(&psurfNew);
  1499.  
  1500.     SetModifiedFlag(TRUE);
  1501.     UpdateAllViews(NULL, 1);
  1502. }
  1503.  
  1504.  
  1505. DWORD CDxtexDoc::DwDepthAt(LONG lwMip)
  1506. {
  1507.     DWORD dwDepth = m_dwDepth;
  1508.     while (lwMip > 0 && dwDepth > 1)
  1509.     {
  1510.         dwDepth /= 2;
  1511.         lwMip--;
  1512.     }
  1513.     return dwDepth;
  1514. }
  1515.  
  1516.  
  1517. void CDxtexDoc::OnFormatChangeSurfaceFmt() 
  1518. {
  1519.     CChangeFmtDlg changeFmtDlg;
  1520.     LPDIRECT3DBASETEXTURE9 ptex;
  1521.  
  1522.     ptex = (m_ptexNew == NULL ? m_ptexOrig : m_ptexNew);
  1523.  
  1524.     if (IsVolumeMap())
  1525.     {
  1526.         D3DVOLUME_DESC vd;
  1527.         ((LPDIRECT3DVOLUMETEXTURE9)ptex)->GetLevelDesc(0, &vd);
  1528.         changeFmtDlg.m_fmt = vd.Format;
  1529.     }
  1530.     else if (IsCubeMap())
  1531.     {
  1532.         D3DSURFACE_DESC sd;
  1533.         ((LPDIRECT3DCUBETEXTURE9)ptex)->GetLevelDesc(0, &sd);
  1534.         changeFmtDlg.m_fmt = sd.Format;
  1535.     }
  1536.     else
  1537.     {
  1538.         D3DSURFACE_DESC sd;
  1539.         ((LPDIRECT3DTEXTURE9)ptex)->GetLevelDesc(0, &sd);
  1540.         changeFmtDlg.m_fmt = sd.Format;
  1541.     }
  1542.  
  1543.     changeFmtDlg.m_bVolume = IsVolumeMap();
  1544.  
  1545.     if (IDCANCEL == changeFmtDlg.DoModal())
  1546.         return;
  1547.  
  1548.     Compress(changeFmtDlg.m_fmt, TRUE);
  1549. }
  1550.  
  1551.  
  1552. void CDxtexDoc::OnUpdateFileOpenAlpha(CCmdUI* pCmdUI) 
  1553. {
  1554.     pCmdUI->Enable(!IsCubeMap() && !IsVolumeMap()); 
  1555. }
  1556.  
  1557.  
  1558. void CDxtexDoc::OnUpdateFormatGenerateMipmaps(CCmdUI* pCmdUI) 
  1559. {
  1560.     pCmdUI->Enable(m_numMips <= 1); 
  1561. }
  1562.  
  1563.  
  1564. void CDxtexDoc::OnUpdateFormatChangeCubeMapFaces(CCmdUI* pCmdUI) 
  1565. {
  1566.     pCmdUI->Enable(!IsCubeMap() && !IsVolumeMap()); 
  1567. }
  1568.  
  1569.  
  1570. void CDxtexDoc::OnUpdateFormatMakeIntoVolumeMap(CCmdUI* pCmdUI) 
  1571. {
  1572.     pCmdUI->Enable(!IsCubeMap() && !IsVolumeMap());
  1573. }
  1574.  
  1575.  
  1576. void CDxtexDoc::OnFormatResize() 
  1577. {
  1578.     CResizeDialog resizeDialog;
  1579.  
  1580.     resizeDialog.m_oldWidth.Format("%d", m_dwWidth);
  1581.     resizeDialog.m_oldHeight.Format("%d", m_dwHeight);
  1582.     resizeDialog.m_newWidth = m_dwWidth;
  1583.     resizeDialog.m_newHeight = m_dwHeight;
  1584.     resizeDialog.m_oldWidth.Format("%d", m_dwWidth);
  1585.     if( IDOK == resizeDialog.DoModal() )
  1586.         Resize(resizeDialog.m_newWidth, resizeDialog.m_newHeight);
  1587. }
  1588.  
  1589.  
  1590. void CDxtexDoc::OnUpdateFormatResize(CCmdUI* pCmdUI) 
  1591. {
  1592.     pCmdUI->Enable(!IsCubeMap() && !IsVolumeMap());
  1593. }
  1594.